using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Collections;
using AjGenesisStudio.Properties;
using AjGenesisStudio.Syntax;
using AjGenesisStudio.Commands;

namespace AjGenesisStudio
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
            Global.Instance.MainForm = this;
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            LoadSettings();
            FillRecents();
            FillExternalTools();
            OpenArguments();
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            SaveSettings();
        }

        private void LoadSettings()
        {
            ToolStripManager.LoadSettings(this);
            this.Visible = true;
            mnuToolbarStandard.Checked = toolStandard.Visible;
            mnuToolbarTemplate.Checked = toolTemplate.Visible;
            mnuViewOutput.Checked = Settings.Default.ShowOutput;
            mnuViewPrjExplorer.Checked = Settings.Default.ShowProjectExplorer;
            mnuViewOutput_CheckedChanged(null, null);
            mnuViewPrjExplorer_CheckedChanged(null, null);
            SyntaxHelper.FillCombo(cboTemplateSyntax);
        }

        private void SaveSettings()
        {
            ToolStripManager.SaveSettings(this);
            Settings.Default.ShowOutput = mnuViewOutput.Checked;
            Settings.Default.ShowProjectExplorer = mnuViewPrjExplorer.Checked;
            Settings.Default.Save();
        }

        private void FillRecents()
        {
            ToolStripMenuItem item;
            if (Settings.Default.RecentFiles != null)
            {
                foreach (string value in Settings.Default.RecentFiles)
                {
                    item = new ToolStripMenuItem();
                    item.Text = value;
                    item.Visible = true;
                    item.Click += mnuOpenRecentFile_Click;
                    mnuRecentFiles.DropDownItems.Insert(0, item);
                }
            }
            if (Settings.Default.RecentProjects != null)
            {
                foreach (string value in Settings.Default.RecentProjects)
                {
                    item = new ToolStripMenuItem();
                    item.Text = value;
                    item.Visible = true;
                    item.Click += mnuOpenRecentProject_Click;
                    mnuRecentProjects.DropDownItems.Insert(0, item);
                }
            }
            mnuRecentFiles.Enabled = (mnuRecentFiles.DropDownItems.Count > 0);
            mnuRecentProjects.Enabled = (mnuRecentProjects.DropDownItems.Count > 0);
        }
        
        public void FillExternalTools()
        {
            ToolStripMenuItem item;
            ArrayList lst;

            lst = Settings.Default.ExternalTools;
            if (lst == null) lst = new ArrayList();

            for (int i = 0; i < mnuTools.DropDownItems.Count; i++)
            {
                if (mnuTools.DropDownItems[i].Tag != null)
                {
                    mnuTools.DropDownItems.RemoveAt(i);
                    i--;
                }
            }

            for (int i = lst.Count - 1; i >= 0; i--)
            {
                Tools.ExternalTool tool = (Tools.ExternalTool)lst[i];
                item = new ToolStripMenuItem();
                item.Text = tool.Title;
                item.Tag = tool;
                item.Visible = true;
                item.Click += mnuToolsExecute_Click;

                mnuTools.DropDownItems.Insert(0, item);
            }
        }

        #region Menues and toolbars events

        #region Edit commands

        private void mnuFind_Click(object sender, EventArgs e)
        {
            this.CmFind();
        }

        private void mnuReplace_Click(object sender, EventArgs e)
        {
            this.CmReplace();
        }

        private void mnuGoToLine_Click(object sender, EventArgs e)
        {
            this.CmGoToLine();
        }

        private void mnuSelectAll_Click(object sender, EventArgs e)
        {
            this.CmSelectAll();
        }

        private void mnuDelete_Click(object sender, EventArgs e)
        {
            this.CmDelete();
        }

        private void mnuPaste_Click(object sender, EventArgs e)
        {
            this.CmPaste();
        }

        private void mnuCopy_Click(object sender, EventArgs e)
        {
            this.CmCopy();
        }

        private void mnuCut_Click(object sender, EventArgs e)
        {
            this.CmCut();
        }

        private void mnuRedo_Click(object sender, EventArgs e)
        {
            this.CmRedo();
        }

        private void mnuUndo_Click(object sender, EventArgs e)
        {
            this.CmUndo();
        }

        #endregion

        public void mnuToolsExecute_Click(object sender, EventArgs e)
        {
            try
            {
                ToolStripMenuItem item = (ToolStripMenuItem)sender;
                Tools.ExternalTool tool = (Tools.ExternalTool)item.Tag;
                ExecuteExternalToolCommand cmd = new ExecuteExternalToolCommand();
                cmd.Tool = tool;
                cmd.Execute();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void mnuNewFile_Click(object sender, EventArgs e)
        {
            Dialogs.NewFileDialog dlg = new Dialogs.NewFileDialog();
            dlg.ShowDialog(this);
        }

        private void mnuNewProject_Click(object sender, EventArgs e)
        {
            Dialogs.NewProjectDialog dlg = new Dialogs.NewProjectDialog();
            dlg.ShowDialog(this);
        }

        private void mnuExternalTools_Click(object sender, EventArgs e)
        {
            Dialogs.ExternalToolsDialog dlg = new Dialogs.ExternalToolsDialog();
            dlg.ShowDialog(this);
        }

        private void mnuAbout_Click(object sender, EventArgs e)
        {
            AboutForm frm = new AboutForm();
            frm.ShowDialog(this);
        }

        private void mnuNewTemplate_Click(object sender, EventArgs e)
        {
            this.CmNewFile("tpl");
        }

        private void mnuNewModel_Click(object sender, EventArgs e)
        {
            this.CmNewFile("xml");
        }

        private void mnuNewTask_Click(object sender, EventArgs e)
        {
            this.CmNewFile("ajg");
        }

        private void mnuNewBuild_Click(object sender, EventArgs e)
        {
            this.CmNewFile("build");
        }

        private void mnuSaveAs_Click(object sender, EventArgs e)
        {
            this.CmSaveAs();
        }

        private void btnRun_Click(object sender, EventArgs e)
        {
            this.CmRun();
        }

        private void mnuOpenFile_Click(object sender, EventArgs e)
        {
            this.CmOpen();
        }

        private void mnuOpenProject_Click(object sender, EventArgs e)
        {
            this.CmOpenFolder();
        }

        private void mnuOpenRecentFile_Click(object sender, EventArgs e)
        {
            this.CmOpen(((ToolStripMenuItem)sender).Text);
        }

        private void mnuOpenRecentProject_Click(object sender, EventArgs e)
        {
            this.CmOpenFolder(((ToolStripMenuItem)sender).Text);
        }

        private void mnuToolbarStandard_Click(object sender, EventArgs e)
        {
            if (mnuToolbarStandard.Checked)
                toolStandard.Show();
            else
                toolStandard.Hide();
        }

        private void mnuToolbarTemplate_Click(object sender, EventArgs e)
        {
            if (mnuToolbarTemplate.Checked)
                toolTemplate.Show();
            else
                toolTemplate.Hide();
        }

        private void mnuViewPrjExplorer_CheckedChanged(object sender, EventArgs e)
        {
            if (mnuViewPrjExplorer.Checked)
                ShowProjectExplorer();
            else
                Panels.ExplorerPanel.Instance.Hide();
        }

        private void mnuViewOutput_CheckedChanged(object sender, EventArgs e)
        {
            if (mnuViewOutput.Checked)
                ShowOutputLog();
            else
                Panels.OutputPanel.Instance.Hide();
        }

        private void mnuSave_Click(object sender, EventArgs e)
        {
            this.CmSave();
        }

        private void btnOpen_Click(object sender, EventArgs e)
        {
            this.CmOpen();
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            this.CmSave();
        }

        private void btnCut_Click(object sender, EventArgs e)
        {
            this.CmCut();
        }

        private void btnCopy_Click(object sender, EventArgs e)
        {
            this.CmCopy();
        }

        private void btnPaste_Click(object sender, EventArgs e)
        {
            this.CmCut();
        }

        private void btnUndo_Click(object sender, EventArgs e)
        {
            this.CmUndo();
        }

        private void btnRedo_Click(object sender, EventArgs e)
        {
            this.CmRedo();
        }

        private void mnuWindowSplitV_Click(object sender, EventArgs e)
        {
            this.CmSplitV();
        }

        private void mnuWindowSplitH_Click(object sender, EventArgs e)
        {
            this.CmSplitH();
        }

        private void mnuExportHTML_Click(object sender, EventArgs e)
        {
            this.CmExportHTML();
        }

        private void mnuFilePrint_Click(object sender, EventArgs e)
        {
            this.CmPrint();
        }

        private void mnuFilePreview_Click(object sender, EventArgs e)
        {
            this.CmPreview();
        }

        private void mnuViewFontInc_Click(object sender, EventArgs e)
        {
            this.CmFontInc();
        }

        private void mnuViewFontDec_Click(object sender, EventArgs e)
        {
            this.CmFontDec();
        }

        private void mnuBtnNewTemplate_Click(object sender, EventArgs e)
        {
            this.CmNewFile("tpl");
        }

        private void mnuBtnNewModel_Click(object sender, EventArgs e)
        {
            this.CmNewFile("xml");
        }

        private void mnuBtnNewTask_Click(object sender, EventArgs e)
        {
            this.CmNewFile("ajg");
        }

        private void mnuBtnNewBuild_Click(object sender, EventArgs e)
        {
            this.CmNewFile("build");
        }

        private void mnuBtnNewFile_Click(object sender, EventArgs e)
        {
            Dialogs.NewFileDialog dlg = new Dialogs.NewFileDialog();
            dlg.ShowDialog(this);
        }

        #endregion

        #region Commands

        void CmRun()
        {
            (new ExecuteCommand()).Execute();
        }

        void CmNewFile(string extension)
        {
            (new NewFileCommand()).Execute(extension);
        }

        void CmSaveAs()
        {
            (new SaveAsCommand()).Execute();
        }

        void CmOpen()
        {
            (new OpenCommand()).Execute();
        }

        void CmOpen(string file)
        {
            (new OpenCommand()).Execute(file);
        }

        void CmOpenFolder()
        {
            (new OpenProjectCommand()).Execute();
        }

        void CmOpenFolder(string path)
        {
            (new OpenProjectCommand()).Execute(path);
        }

        void CmSave()
        {
            (new SaveCommand()).Execute();
        }

        void CmCopy()
        {
            ExecuteEditCmd(EDITCMDTYPE.Copy);
        }

        void CmCut()
        {
            ExecuteEditCmd(EDITCMDTYPE.Cut);
        }

        void CmDelete()
        {
            ExecuteEditCmd(EDITCMDTYPE.Delete);
        }

        void CmFind()
        {
            ExecuteEditCmd(EDITCMDTYPE.Find);
        }

        void CmGoToLine()
        {
            ExecuteEditCmd(EDITCMDTYPE.GoToLine);
        }

        void CmPaste()
        {
            ExecuteEditCmd(EDITCMDTYPE.Paste);
        }

        void CmRedo()
        {
            ExecuteEditCmd(EDITCMDTYPE.Redo);
        }

        void CmReplace()
        {
            ExecuteEditCmd(EDITCMDTYPE.Replace);
        }

        void CmSelectAll()
        {
            ExecuteEditCmd(EDITCMDTYPE.SelectAll);
        }

        void CmUndo()
        {
            ExecuteEditCmd(EDITCMDTYPE.Undo);
        }

        void CmSplitH()
        {
            ExecuteEditCmd(EDITCMDTYPE.SplitH);
        }

        void CmSplitV()
        {
            ExecuteEditCmd(EDITCMDTYPE.SplitV);
        }

        private void ExecuteEditCmd(EDITCMDTYPE e)
        {
            (new EditCommand(e)).Execute();
        }

        private void CmExportHTML()
        {
            (new ExportHtmlCommand()).Execute();
        }

        void CmPrint()
        {
            (new PrintCommand()).Execute();
        }

        void CmPreview()
        {
            (new PrintPreviewCommand()).Execute();
        }

        void CmFontInc()
        {
            (new IncreaseFontCommand()).Execute();
        }

        void CmFontDec()
        {
            (new DecreaseFontCommand()).Execute();
        }
        #endregion

        private void cboTemplateSyntax_SelectedIndexChanged(object sender, EventArgs e)
        {
            Documents.Document doc = GetActiveDocument();
            Documents.TemplateDocument tpl;

            if (doc is Documents.TemplateDocument)
            {
                tpl = (Documents.TemplateDocument)doc;
                tpl.OutputSyntax = (Syntax.Syntax)cboTemplateSyntax.SelectedItem;
            }
        }

        public void ShowProjectExplorer()
        {
            Panels.ExplorerPanel explorer = Panels.ExplorerPanel.Instance;
            if (!explorer.IsActivated)
            {
                explorer.Show(dockcont, Fireball.Docking.DockState.DockRightAutoHide);
                explorer.Activate();
            }
        }

        public void ShowOutputLog()
        {
            Panels.OutputPanel output = Panels.OutputPanel.Instance;
            if (!output.IsActivated)
            {
                output.Show(dockcont, Fireball.Docking.DockState.DockBottom);
                output.Activate();
            }
        }

        public void ShowDocument(Documents.Document doc)
        {
            doc.Show(dockcont, Fireball.Docking.DockState.Document);
            doc.Activate();
        }

        public Documents.Document GetActiveDocument()
        {
            if (dockcont.ActiveDocument is Documents.Document)
                return (Documents.Document)dockcont.ActiveDocument;
            else
                return null;
        }

        public List<Documents.Document> GetDocuments()
        {
            List<Documents.Document> docs;
            docs = new List<Documents.Document>();

            foreach (Fireball.Docking.IDockableWindow d in dockcont.Documents)
                if (dockcont.ActiveDocument is Documents.Document)
                    docs.Add((Documents.Document)d);

            return docs;
        }

        private void dockcont_ActiveDocumentChanged(object sender, EventArgs e)
        {
            Documents.Document doc = GetActiveDocument();
            if (doc != null)
            {
                if (doc is Documents.TemplateDocument)
                {
                    Syntax.Syntax syn = ((Documents.TemplateDocument)doc).OutputSyntax;

                    if (syn != null)
                        cboTemplateSyntax.Text = syn.Name;
                    else
                        cboTemplateSyntax.SelectedIndex = -1;
                }
            }
        }

        private void MainForm_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop, false))
                e.Effect = DragDropEffects.All;
        }

        private void MainForm_DragDrop(object sender, DragEventArgs e)
        {
            string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
            OpenFiles(files);
        }

        private void OpenArguments()
        {
            string[] files = System.Environment.GetCommandLineArgs();
            
            if (files.Length > 1)
            {
                OpenFiles(files);
            }
        }

        private void OpenFiles(string[] files)
        {
            bool project_open = false;

            foreach (string f in files)
            {
                if (Directory.Exists(f))
                {//es una carpeta, lo abro como proyecto
                    if (!project_open)
                    {
                        (new OpenProjectCommand()).Execute(f);
                        project_open = true; //solo abro la primera carpeta
                    }
                }
                else
                {
                    if (File.Exists(f)) //abro todos los archivos
                        (new OpenCommand()).Execute(f);
                }
            }
        }

        public void SetStatus(string status)
        {
            lblStatus.Text = status;
            this.status.Refresh();
            Application.DoEvents();
        }
    }
}